home *** CD-ROM | disk | FTP | other *** search
/ Aminet 7 / Aminet 7 - August 1995.iso / Aminet / text / hyper / ADtoHT2_1.lha / Source.lha / Autodocs.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-23  |  37.8 KB  |  1,396 lines

  1. #include <proto/alib.h>
  2. #include <proto/exec.h>
  3.  
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <ctype.h>
  8.  
  9. /************************************************************************/
  10.  
  11. #include "Includes.h"
  12. #include "Autodocs.h"
  13. #include "File.h"
  14. #include "FormatNode.h"
  15. #include "AdditionalDocs.h"
  16.  
  17. /************************************************************************/
  18.  
  19. static struct AutodocModuleNode *ExecModuleNode;
  20.  
  21. /************************************************************************/
  22.  
  23. struct AVLTree AutodocFileTree = {NULL, nodecasecmp};
  24. struct AVLTree AutodocModuleTree = {NULL, nodecmp};
  25. struct AVLTree AutodocNodeTree = {NULL, nodecmp};
  26.  
  27. /************************************************************************/
  28. /*                                                                      */
  29. /* Create a new AutodocNodeNode                                         */
  30. /*                                                                      */
  31. /************************************************************************/
  32.  
  33. struct AutodocNodeNode *
  34. CreateAutodocNode (char *Name, struct AutodocModuleNode *AutodocModuleNode)
  35.  
  36. {
  37.   struct AutodocNode *AutodocNode;
  38.   struct AutodocNodeNode *AutodocNodeNode;
  39.   struct AutodocNodeNode **Current;
  40.  
  41.   if (!(AutodocNode = (struct AutodocNode *) SearchNode (&AutodocNodeTree, Name)))
  42.     {
  43.       AutodocNode = (struct AutodocNode *) CreateNode (Name, sizeof (*AutodocNode));
  44.       AutodocNode->Entries = NULL;
  45.       AutodocNode->Function = TRUE;
  46.       AVL_InsertNode (&AutodocNodeTree, &AutodocNode->AnyNode.AVLNode);
  47.     }
  48.   AutodocNodeNode = xmalloc (sizeof (*AutodocNodeNode));
  49.   AutodocNodeNode->AnyNode.Name = AutodocNode->AnyNode.Name;
  50.   AutodocNodeNode->AutodocModuleNode = AutodocModuleNode;
  51.   AutodocNodeNode->AutodocNode = AutodocNode;
  52.  
  53.   Current = &AutodocNode->Entries;
  54.   if (AutodocModuleNode != ExecModuleNode)
  55.     {
  56.       if (*Current && (*Current)->AutodocModuleNode == ExecModuleNode)
  57.     {
  58.       Current = &(*Current)->Next;
  59.     }
  60.       while (*Current &&
  61.          strcasecmp ((*Current)->AutodocModuleNode->AnyNode.Name,
  62.              AutodocNodeNode->AutodocModuleNode->AnyNode.Name) < 0)
  63.     {
  64.       Current = &(*Current)->Next;
  65.     }
  66.     }
  67.   AutodocNodeNode->Next = *Current;
  68.   *Current = AutodocNodeNode;
  69.  
  70.   return AutodocNodeNode;
  71. }
  72.  
  73. /************************************************************************/
  74. /*                                                                      */
  75. /* Find the "TABLE OF CONTENTS" line                                    */
  76. /*                                                                      */
  77. /************************************************************************/
  78.  
  79. static void
  80. FindTOC (void)
  81.  
  82. {
  83.   struct Word *Word;
  84.   int Skipped;
  85.  
  86.   Skipped=FALSE;
  87.   Word = ReadWord (TRUE);
  88.   while (Word->Length)
  89.     {
  90.       if (!strcasecmp (Word->Word, "TABLE"))
  91.     {
  92.       struct Word *NextWord;
  93.  
  94.       NextWord = ReadWord (TRUE);
  95.       if (!NextWord->Newline && !strcasecmp (NextWord->Word, "OF"))
  96.         {
  97.           struct Word *NextNextWord;
  98.  
  99.           NextNextWord = ReadWord (TRUE);
  100.           if (!NextNextWord->Newline && !strcasecmp (NextNextWord->Word, "CONTENTS"))
  101.         {
  102.           FreeWord(NextNextWord);
  103.           FreeWord(NextWord);
  104.           FreeWord(Word);
  105.           if (Skipped && !Pass2)
  106.             {
  107.               fprintf(stderr,"%s: skipped garbage before \x22TABLE OF CONTENTS\x22\n",ReadFilename);
  108.               SetRC(RETURN_WARN);
  109.             }
  110.           return;
  111.         }
  112.           UnreadWord(NextNextWord);
  113.         }
  114.       UnreadWord(NextWord);
  115.     }
  116.       if (Word->Newline && Word->Word[0]=='\x0c')
  117.     {
  118.       FreeWord(Word);
  119.       Word=ReadWord(TRUE);
  120.     }
  121.       else
  122.     {
  123.       do
  124.         {
  125.           FreeWord(Word);
  126.           Word=ReadWord(TRUE);
  127.         }
  128.       while (!Word->Newline && Word->Length);
  129.     }
  130.       Skipped=TRUE;
  131.     }
  132.   fprintf (stderr, "%s: no \x22TABLE OF CONTENTS\x22 found\n", ReadFilename);
  133.   CloseAll (RETURN_ERROR);
  134. }
  135.  
  136. /************************************************************************/
  137. /*                                                                      */
  138. /* Read and process a table of contents entry                           */
  139. /* FALSE if no entry was found                                          */
  140. /*                                                                      */
  141. /************************************************************************/
  142.  
  143. static int
  144. ReadTOCLine (struct AutodocFileNode *AutodocFileNode)
  145.  
  146. {
  147.   struct Word *Word;
  148.  
  149.   Word = ReadWord (FALSE);
  150.   if (strcmp ("\x0c", Word->Word))
  151.     {
  152.       char *Module;
  153.       int Information;
  154.       struct AutodocModuleNode *AutodocModuleNode;
  155.  
  156.       UnreadWord (Word);
  157.  
  158.       Module = ReadUntil ("/");
  159.       FreeWord (ReadWord (FALSE));    /* kill the terminator */
  160.  
  161.       /* get node name */
  162.       Information = FALSE;
  163.       Word = ReadWord (FALSE);
  164.       while (Word->Word[0] == '-')
  165.     {
  166.       Information = TRUE;
  167.       FreeWord (Word);
  168.       Word = ReadWord (FALSE);
  169.     }
  170.  
  171.       if (!(AutodocModuleNode = (struct AutodocModuleNode *) SearchNode (&AutodocModuleTree, Module)))
  172.     {
  173.       struct AutodocModuleNode **CurrentNode;
  174.  
  175.       AutodocModuleNode = xmalloc (sizeof (*AutodocModuleNode));
  176.       AutodocModuleNode->AnyNode.Name = Module;
  177.       AutodocModuleNode->AutodocFileNode = AutodocFileNode;
  178.       AutodocModuleNode->InfoNodes = NULL;
  179.       AutodocModuleNode->Nodes.Root = NULL;
  180.       AutodocModuleNode->Nodes.CompareNodes = AutodocNodeTree.CompareNodes;
  181.       for (CurrentNode = &AutodocFileNode->Modules; *CurrentNode; CurrentNode = &(*CurrentNode)->Next)
  182.         ;
  183.       *CurrentNode = AutodocModuleNode;
  184.       AutodocModuleNode->Next = NULL;
  185.       AVL_InsertNode (&AutodocModuleTree, (struct AVLNode *) AutodocModuleNode);
  186.       if (!strcmp (Module, "exec.library"))
  187.         {
  188.           ExecModuleNode = AutodocModuleNode;
  189.         }
  190.     }
  191.       else
  192.     {
  193.       free (Module);
  194.     }
  195.  
  196.       if (Information)
  197.     {
  198.       struct AutodocInfoNode *AutodocInfoNode;
  199.       struct AutodocInfoNode **CurrentNode;
  200.  
  201.       AutodocInfoNode = xmalloc (sizeof (*AutodocInfoNode));
  202.       AutodocInfoNode->Next = NULL;
  203.       AutodocInfoNode->Name = xstrdup (Word->Word);
  204.       AutodocInfoNode->Found = FALSE;
  205.       for (CurrentNode = &AutodocModuleNode->InfoNodes;
  206.            *CurrentNode;
  207.            CurrentNode = &(*CurrentNode)->Next)
  208.         ;
  209.       *CurrentNode = AutodocInfoNode;
  210.     }
  211.       else
  212.     {
  213.       struct AutodocNodeNode *AutodocNodeNode;
  214.  
  215.       AutodocNodeNode = CreateAutodocNode (Word->Word, AutodocModuleNode);
  216.       if (!strcmp (AutodocModuleNode->AnyNode.Name, "SAD"))
  217.         {
  218.           AutodocNodeNode->AutodocNode->Function = FALSE;
  219.         }
  220.       else
  221.         {
  222.           struct IncludeItemNode *IncludeItemNode;
  223.  
  224.           AutodocNodeNode->AutodocNode->Function =
  225.         (!(IncludeItemNode = (struct IncludeItemNode *)
  226.         SearchNode (&DefinesTree, AutodocNodeNode->AnyNode.Name)) ||
  227.          IncludeItemNode->Function);
  228.         }
  229.  
  230.       AutodocNodeNode->RealNode = AutodocNodeNode;
  231.       AutodocNodeNode->Found = FALSE;
  232.       if (AVL_InsertNode (&AutodocModuleNode->Nodes, &AutodocNodeNode->AnyNode.AVLNode))
  233.         {
  234.           fprintf (stderr, "%s, %lu: duplicate definition of \x22%s/%s\x22\n",
  235.                ReadFilename, Word->Line,
  236.                AutodocModuleNode->AnyNode.Name, AutodocNodeNode->AnyNode.Name);
  237.           CloseAll (RETURN_ERROR);
  238.         }
  239.     }
  240.       FreeWord (Word);
  241.       Word = ReadWord (FALSE);
  242.       while (!Word->Newline)
  243.     {
  244.       FreeWord (Word);
  245.       Word = ReadWord (FALSE);
  246.     }
  247.       UnreadWord (Word);
  248.       return TRUE;
  249.     }
  250.   FreeWord(Word);
  251.   return FALSE;
  252. }
  253.  
  254. /************************************************************************/
  255. /*                                                                      */
  256. /* Get the next label for TOC output                                    */
  257. /* Parameters: AutodocFileNode==NULL means AutodocModuleNode is valid   */
  258. /*                                                                      */
  259. /************************************************************************/
  260.  
  261. struct FormatParameters
  262. {
  263.   struct AutodocFileNode *AutodocFileNode;
  264.   struct AutodocModuleNode *AutodocModuleNode;
  265.  
  266.   struct AutodocNodeNode *AutodocNodeNode;
  267.   struct AVLStateInfo StateInfo;
  268. };
  269.  
  270. static char *
  271. AutodocNextLabel (char *PrevLabel, void *Parameters)
  272.  
  273. {
  274.   struct FormatParameters *Params;
  275.   char *Label;
  276.   char *t;
  277.  
  278.   Params = (struct FormatParameters *) Parameters;
  279.  
  280.   if (!PrevLabel)
  281.     {
  282.       if (Params->AutodocFileNode)
  283.     {
  284.       Params->AutodocModuleNode = Params->AutodocFileNode->Modules;
  285.     }
  286.       AVL_InitTraversal (&Params->AutodocModuleNode->Nodes, &Params->StateInfo);
  287.     }
  288.   else
  289.     {
  290.       if (!PrevLabel[0])
  291.     {
  292.       AVL_InitTraversal (&Params->AutodocModuleNode->Nodes, &Params->StateInfo);
  293.     }
  294.       free (PrevLabel);
  295.     }
  296.  
  297.   if (!(Params->AutodocNodeNode = (struct AutodocNodeNode *) AVL_InOrder (&Params->StateInfo)))
  298.     {
  299.       if (Params->AutodocFileNode)
  300.     {
  301.       if ((Params->AutodocModuleNode = Params->AutodocModuleNode->Next))
  302.         {
  303.           return xstrdup ("");
  304.         }
  305.     }
  306.       return NULL;
  307.     }
  308.  
  309.   Label = xmalloc (strlen (Params->AutodocNodeNode->AnyNode.Name) +
  310.            (Params->AutodocNodeNode->AutodocNode->Function ? 3 : 1));
  311.   t = stpcpy (Label, Params->AutodocNodeNode->AnyNode.Name);
  312.   if (Params->AutodocNodeNode->AutodocNode->Function)
  313.     strcpy (t, "()");
  314.   return Label;
  315. }
  316.  
  317. /************************************************************************/
  318. /*                                                                      */
  319. /* Output the link information for current label                        */
  320. /*                                                                      */
  321. /************************************************************************/
  322.  
  323. static void 
  324. AutodocPrintLink (void *Parameters)
  325.  
  326. {
  327.   WPrintf ("\x22%s%s",
  328.        ((struct FormatParameters *) Parameters)->AutodocNodeNode->RealNode->AnyNode.Name,
  329.        Arguments.Parentheses ? "()\x22" : "\x22");
  330. }
  331.  
  332. /************************************************************************/
  333. /*                                                                      */
  334. /* Output the table of contents                                         */
  335. /*                                                                      */
  336. /************************************************************************/
  337.  
  338. static void
  339. OutputTOC (struct AutodocFileNode *AutodocFileNode)
  340.  
  341. {
  342.   struct FormatParameters FormatParameters;
  343.   struct AutodocModuleNode *AutodocModuleNode;
  344.   int *ColWidth;
  345.  
  346.   WPrintf ("\n@NODE MAIN \x22%s\x22\n", AutodocFileNode->AnyNode.Name);
  347.   if (GlobalTOCFilename)
  348.     {
  349.       WPrintf("@TOC \x22%s/MAIN\x22\n",GlobalTOCFilename);
  350.     }
  351.  
  352.   FormatParameters.AutodocFileNode = AutodocFileNode;
  353.   ColWidth = FormatNode (AutodocNextLabel, &FormatParameters);
  354.  
  355.   FormatParameters.AutodocFileNode = NULL;
  356.   AutodocModuleNode = AutodocFileNode->Modules;
  357.   while (AutodocModuleNode)
  358.     {
  359.       struct AutodocInfoNode *AutodocInfoNode;
  360.  
  361.       WPrintf("\n");
  362.       WHeadline (AutodocModuleNode->AnyNode.Name);
  363.       WPrintf ("\n");
  364.  
  365.       for (AutodocInfoNode = AutodocModuleNode->InfoNodes;
  366.        AutodocInfoNode;
  367.        AutodocInfoNode = AutodocInfoNode->Next)
  368.     {
  369.       WPrintf ("@{\x22%s\x22 LINK \x22%s\x22}\n",
  370.            AutodocInfoNode->Name,
  371.            AutodocInfoNode->Name);
  372.     }
  373.       if (AutodocModuleNode->InfoNodes)
  374.     WPrintf ("\n");
  375.  
  376.       FormatParameters.AutodocModuleNode = AutodocModuleNode;
  377.       PrintNode (AutodocNextLabel, AutodocPrintLink, &FormatParameters, ColWidth);
  378.  
  379.       if ((AutodocModuleNode = AutodocModuleNode->Next))
  380.     WPrintf ("\n\n");
  381.     }
  382.   free (ColWidth);
  383.   WPrintf ("\n@ENDNODE\n");
  384. }
  385.  
  386. /************************************************************************/
  387. /*                                                                      */
  388. /* Check if the next stuff read is () (no newlines).                    */
  389. /* If yes, echo it. If no, do nothing.                                  */
  390. /* This function is used to get the '()' into a button (looks better).  */
  391. /*                                                                      */
  392. /************************************************************************/
  393.  
  394. static void 
  395. DoParentheses (void)
  396.  
  397. {
  398.   struct Word *Word;
  399.  
  400.   Word = ReadWord (TRUE);
  401.   if (Word->Word[0] == '(' && !Word->Newline)
  402.     {
  403.       struct Word *NextWord;
  404.  
  405.       NextWord = ReadWord (TRUE);
  406.       if (NextWord->Word[0] == ')' && !NextWord->Newline)
  407.     {
  408.       WriteWord (Word);
  409.       WriteWord (NextWord);
  410.       FreeWord (Word);
  411.       FreeWord (NextWord);
  412.       return;
  413.     }
  414.       UnreadWord (NextWord);
  415.     }
  416.   UnreadWord (Word);
  417. }
  418.  
  419. /************************************************************************/
  420. /*                                                                      */
  421. /* Check if the word references a module.                               */
  422. /* If yes, make a link and return TRUE. If no, do nothing and return    */
  423. /* FALSE.                                                               */
  424. /* Handles all cases, including module/functionname                     */
  425. /*                                                                      */
  426. /************************************************************************/
  427.  
  428. static int 
  429. DoModule (struct Word *Word, struct AutodocNodeNode *CurrentAutodocNode)
  430.  
  431. {
  432.   struct AutodocModuleNode *AutodocModuleNode;
  433.  
  434.   if (Word->Length > 5 && (AutodocModuleNode = (struct AutodocModuleNode *) SearchNode (&AutodocModuleTree, Word->Word)))
  435.     {
  436.       struct Word *NextWord;
  437.       struct Word *NodeName;    /* is only used when initialized */
  438.  
  439.       WriteWhitespace (Word);
  440.  
  441.       NextWord = ReadWord (TRUE);
  442.       if (NextWord->Word[0] == '/')
  443.     {
  444.       struct AutodocNodeNode *AutodocNodeNode;
  445.  
  446.       NodeName = ReadWord (TRUE);
  447.       if ((AutodocNodeNode = (struct AutodocNodeNode *) SearchNode (&AutodocModuleNode->Nodes, NodeName->Word)))
  448.         {
  449.           if (AutodocNodeNode->RealNode != CurrentAutodocNode)
  450.         {
  451.           if (NextWord->Newline || NodeName->Newline)
  452.             {
  453.               WriteWord (Word);
  454.               WriteWord (NextWord);
  455.               WriteWhitespace (NodeName);
  456.               WPrintf ("@{\x22");
  457.             }
  458.           else
  459.             {
  460.               WPrintf ("@{\x22");
  461.               WriteWord (Word);
  462.               WriteWord (NextWord);
  463.             }
  464.           WriteWord (NodeName);
  465.  
  466.           DoParentheses ();
  467.  
  468.           WPrintf ("\x22 LINK \x22");
  469.           if (!(CurrentAutodocNode &&
  470.             CurrentAutodocNode->AutodocModuleNode->AutodocFileNode == AutodocModuleNode->AutodocFileNode))
  471.             {
  472.               WPrintf ("%s/", AutodocModuleNode->AutodocFileNode->LinkName);
  473.             }
  474.           WPrintf ("%s%s\x22}",
  475.                AutodocNodeNode->RealNode->AnyNode.Name,
  476.                (Arguments.Parentheses && AutodocNodeNode->AutodocNode->Function) ? "()" : "");
  477.         }
  478.           else
  479.         {
  480.           WriteWord (Word);
  481.           WriteWord (NextWord);
  482.           WriteWord (NodeName);
  483.         }
  484.           FreeWord (NodeName);
  485.           FreeWord (NextWord);
  486.           return TRUE;
  487.         }
  488.     }
  489.       else
  490.     {
  491.       UnreadWord (NextWord);
  492.       NextWord = NULL;
  493.     }
  494.       if (!CurrentAutodocNode ||
  495.       CurrentAutodocNode->AutodocModuleNode != AutodocModuleNode)
  496.     {
  497.       WriteWhitespace (Word);
  498.       WPrintf ("@{\x22%s\x22 LINK \x22%s/MAIN\x22}",
  499.            Word->Word,
  500.            AutodocModuleNode->AutodocFileNode->LinkName);
  501.     }
  502.       else
  503.     {
  504.       WriteWord (Word);
  505.     }
  506.       if (NextWord)
  507.     {
  508.       WriteWord (NextWord);
  509.       WriteWord (NodeName);
  510.       FreeWord (NextWord);
  511.       FreeWord (NodeName);
  512.     }
  513.       return TRUE;
  514.     }
  515.   return FALSE;
  516. }
  517.  
  518. /************************************************************************/
  519. /*                                                                      */
  520. /* Check if the word references an header file.                         */
  521. /* If yes, make a link and return TRUE. If no, do nothing and return    */
  522. /* FALSE.                                                               */
  523. /*                                                                      */
  524. /************************************************************************/
  525.  
  526. static int 
  527. DoHeader (struct Word *Word, struct IncludeFileNode *CurrentIncludeFile)
  528.  
  529. {
  530.   if (Word->Length > 1)
  531.     {
  532.       struct MinList WordList;
  533.       char *Filename;
  534.  
  535.       NewList ((struct List *) &WordList);
  536.       AddTail ((struct List *) &WordList, (struct Node *) &Word->Node);
  537.       Filename = xstrdup (Word->Word);
  538.  
  539.       while (Word)
  540.     {
  541.       Word = ReadWord (TRUE);
  542.       AddTail ((struct List *) &WordList, (struct Node *) &Word->Node);
  543.       if (!Word->Whitespace && !Word->Newline && Word->Word[0] == '/')
  544.         {
  545.           Word = ReadWord (TRUE);
  546.           AddTail ((struct List *) &WordList, (struct Node *) &Word->Node);
  547.           if (!Word->Whitespace && !Word->Newline && Word->Length > 1)
  548.         {
  549.           char *NewFilename;
  550.           struct IncludeFileNode *IncludeFileNode;
  551.  
  552.           NewFilename = xmalloc (strlen (Filename) + 1 + Word->Length + 1);
  553.           stpcpy (stpcpy (stpcpy (NewFilename, Filename), "/"), Word->Word);
  554.           free (Filename);
  555.           Filename = NewFilename;
  556.  
  557.           if ((IncludeFileNode = (struct IncludeFileNode *) SearchNode (&IncludeFileTree, Filename)))
  558.             {
  559.               WriteWhitespace ((struct Word *) WordList.mlh_Head);
  560.               WPrintf ("@{\x22%s\x22 LINK \x22%s/File\x22}", Filename, IncludeFileNode->LinkName);
  561.               Word = (struct Word *) RemTail ((struct List *) &WordList);
  562.               while (!IsListEmpty ((struct List *) &WordList))
  563.             {
  564.               FreeWord (Word);
  565.               Word = (struct Word *) RemTail ((struct List *) &WordList);
  566.             }
  567.               free (Filename);
  568.               return TRUE;
  569.             }
  570.         }
  571.           else
  572.         {
  573.           Word = NULL;
  574.         }
  575.         }
  576.       else
  577.         {
  578.           Word = NULL;
  579.         }
  580.     }
  581.  
  582.       free (Filename);
  583.       Word = (struct Word *) RemTail ((struct List *) &WordList);
  584.       while (!IsListEmpty ((struct List *) &WordList))
  585.     {
  586.       UnreadWord (Word);
  587.       Word = (struct Word *) RemTail ((struct List *) &WordList);
  588.     }
  589.     }
  590.   return FALSE;
  591. }
  592.  
  593. /************************************************************************/
  594. /*                                                                      */
  595. /* Make a link to an autodoc entry.                                     */
  596. /*                                                                      */
  597. /************************************************************************/
  598.  
  599. static void 
  600. WriteAutodocLink (struct Word *Word,
  601.           struct AutodocNodeNode *AutodocNodeNode,
  602.           struct AutodocNodeNode *CurrentAutodocNode)
  603.  
  604. {
  605.   AutodocNodeNode = AutodocNodeNode->RealNode;
  606.  
  607.   WriteWhitespace (Word);
  608.   WPrintf ("@{\x22");
  609.   WriteWord (Word);
  610.   DoParentheses ();
  611.   WPrintf ("\x22 LINK \x22");
  612.   if (!CurrentAutodocNode ||
  613.       CurrentAutodocNode->AutodocModuleNode->AutodocFileNode != AutodocNodeNode->AutodocModuleNode->AutodocFileNode)
  614.     {
  615.       WPrintf ("%s/", AutodocNodeNode->AutodocModuleNode->AutodocFileNode->LinkName);
  616.     }
  617.   WPrintf ("%s%s\x22}",
  618.        AutodocNodeNode->RealNode->AnyNode.Name,
  619.        (Arguments.Parentheses && AutodocNodeNode->AutodocNode->Function) ? "()" : "");
  620. }
  621.  
  622. /************************************************************************/
  623. /*                                                                      */
  624. /* Check if the word references an autodoc node.                        */
  625. /* If yes, make a link and return TRUE. If no, do nothing and return    */
  626. /* FALSE.                                                               */
  627. /* This handles unqualified autodocs.                                   */
  628. /*                                                                      */
  629. /************************************************************************/
  630.  
  631. int 
  632. DoAutodoc (struct Word *Word, struct AutodocNodeNode *CurrentAutodocNode)
  633.  
  634. {
  635.   struct AutodocNode *AutodocNode;
  636.  
  637.   if ((AutodocNode = (struct AutodocNode *) SearchNode (&AutodocNodeTree, Word->Word)))
  638.     {
  639.       struct AutodocNodeNode *AutodocNodeNode;
  640.  
  641.       /* unambiguous link? */
  642.       if (!AutodocNode->Entries->Next)
  643.     {
  644.       if (AutodocNode->Entries->RealNode != CurrentAutodocNode)
  645.         {
  646.           WriteAutodocLink (Word, AutodocNode->Entries, CurrentAutodocNode);
  647.           return TRUE;
  648.         }
  649.       return FALSE;
  650.     }
  651.  
  652.       /* possible link into the same module? */
  653.       if (CurrentAutodocNode)
  654.     {
  655.       for (AutodocNodeNode = AutodocNode->Entries;
  656.            AutodocNodeNode;
  657.            AutodocNodeNode = AutodocNodeNode->Next)
  658.         {
  659.           if (AutodocNodeNode->AutodocModuleNode == CurrentAutodocNode->AutodocModuleNode)
  660.         {
  661.           if (AutodocNodeNode->RealNode != CurrentAutodocNode)
  662.             {
  663.               WriteAutodocLink (Word, AutodocNodeNode, CurrentAutodocNode);
  664.               return TRUE;
  665.             }
  666.           else
  667.             {
  668.               break;
  669.             }
  670.         }
  671.         }
  672.     }
  673.  
  674.       /* possible link into exec.library? */
  675.       if (AutodocNode->Entries->AutodocModuleNode == ExecModuleNode)
  676.     {
  677.       if (AutodocNode->Entries->RealNode != CurrentAutodocNode)
  678.         {
  679.           WriteAutodocLink (Word, AutodocNode->Entries, CurrentAutodocNode);
  680.           return TRUE;
  681.         }
  682.       return FALSE;
  683.     }
  684.  
  685.       /* if we are linking to the name we are currently working on      */
  686.       /* (i.e. CurrentAutodocNode IN AutodocNode->Entries), link to     */
  687.       /* the next entry in the list.                                    */
  688.       if (CurrentAutodocNode && CurrentAutodocNode->AutodocNode == AutodocNode)
  689.     {
  690.       if (CurrentAutodocNode->Next)
  691.         {
  692.           WriteAutodocLink (Word, CurrentAutodocNode->Next, CurrentAutodocNode);
  693.         }
  694.       else
  695.         {
  696.           WriteIdentifier (Word, NULL);
  697.         }
  698.       return TRUE;
  699.     }
  700.  
  701.       /* link to the first entry of the list */
  702.       WriteAutodocLink (Word, AutodocNode->Entries, CurrentAutodocNode);
  703.       return TRUE;
  704.     }
  705.   return FALSE;
  706. }
  707.  
  708. /************************************************************************/
  709. /*                                                                      */
  710. /* Look at the "current line" to see if it is really a headline        */
  711. /*                                                                      */
  712. /************************************************************************/
  713.  
  714. static int IsHeadline(void)
  715.  
  716. {
  717.   struct MinList WordList;
  718.   struct Word *Word;
  719.   int Headline;
  720.  
  721.   NewList((struct List *)&WordList);
  722.   Word=ReadWord(TRUE);
  723.  
  724.   if ((Headline=Word->Length && Word->Newline && Word->Whitespace<=4))
  725.     {
  726.       /* Another bug in the MUI autodocs... */
  727.       if (!strcmp(Word->Word,"SEE_ALSO"))
  728.     {
  729.       struct Word *NewWord;
  730.  
  731.       Word->Length=3;
  732.       Word->Word[3]='\0';
  733.  
  734.       NewWord=xmalloc(sizeof(*NewWord)+4);
  735.       NewWord->Line=Word->Line;
  736.       NewWord->Special=Word->Special;
  737.       NewWord->Length=4;
  738.       NewWord->Whitespace=1;
  739.       NewWord->Newline=0;
  740.       strcpy(NewWord->Word,"ALSO");
  741.  
  742.       UnreadWord(NewWord);
  743.     }
  744.  
  745.       do
  746.     {
  747.       size_t i;
  748.  
  749.       for (i=0; i<Word->Length && (Headline=isupper(Word->Word[i])); i++)
  750.         ;
  751.       AddTail((struct List *)&WordList,(struct Node *)&Word->Node);
  752.       Word=ReadWord(TRUE);
  753.     }
  754.       while (Headline && Word->Length && !Word->Newline);
  755.     }
  756.   do
  757.     {
  758.       UnreadWord(Word);
  759.     }
  760.   while ((Word=(struct Word *)RemTail((struct List *)&WordList)));
  761.   return Headline;
  762. }
  763.  
  764. /************************************************************************/
  765. /*                                                                      */
  766. /* Check if the current line should be appended to the previous line.    */
  767. /*                                                                      */
  768. /************************************************************************/
  769.  
  770. static int AppendLine(void)
  771.  
  772. {
  773.   struct MinList WordList;
  774.   struct Word *Word;
  775.   size_t LineLength;
  776.   int RC;
  777.  
  778.   NewList((struct List *)&WordList);
  779.   LineLength=0;
  780.   RC=FALSE;
  781.   Word=ReadWord(TRUE);
  782.   do
  783.     {
  784.       LineLength+=Word->Whitespace+Word->Length;
  785.       AddTail((struct List *)&WordList,(struct Node *)&Word->Node);
  786.       Word=ReadWord(TRUE);
  787.     }
  788.   while (!Word->Newline && Word->Length);
  789.   UnreadWord(Word);
  790.   if (Word->Whitespace>4 || IsHeadline())
  791.     {
  792.       if (LineLength<4)
  793.     {
  794.       ((struct Word *)WordList.mlh_Head)->Whitespace=1;
  795.       ((struct Word *)WordList.mlh_Head)->Newline=0;
  796.       RC=TRUE;
  797.     }
  798.     }
  799.   while ((Word=(struct Word *)RemTail((struct List *)&WordList)))
  800.     {
  801.       UnreadWord(Word);
  802.     }
  803.   return RC;
  804. }
  805.  
  806. /************************************************************************/
  807. /*                                                                      */
  808. /* Indent all lines until the next "headline" is found.            */
  809. /*                                                                      */
  810. /************************************************************************/
  811.  
  812. static void ReindentParagraph(void)
  813.  
  814. {
  815.   struct MinList WordList;
  816.   struct Word *Word;
  817.   int MinSpaces;
  818.  
  819.   NewList((struct List *)&WordList);
  820.  
  821.   /* step 1: determine the minimum indention of the paragraph ("how far left is the leftmost line?") */
  822.   MinSpaces=8;
  823.   UnreadWord(Word=ReadWord(TRUE));
  824.   while (Word->Length && !IsHeadline())
  825.     {
  826.       Word=ReadWord(TRUE);
  827.       if (Word->Newline && Word->Length && Word->Word[0]!=0x0c && Word->Whitespace<MinSpaces)
  828.     {
  829.       MinSpaces=Word->Whitespace;
  830.     }
  831.       do
  832.     {
  833.       AddTail((struct List *)&WordList,(struct Node *)&Word->Node);
  834.       Word=ReadWord(TRUE);
  835.     }
  836.       while (!Word->Newline && Word->Length);
  837.       UnreadWord(Word);
  838.     }
  839.  
  840.   /* now, indent the whole thing by 8-MinSpaces spaces. */
  841.   while ((Word=(struct Word *)RemTail((struct List *)&WordList)))
  842.     {
  843.       if (Word->Newline)
  844.     {
  845.       Word->Whitespace+=(8-MinSpaces);
  846.     }
  847.       UnreadWord(Word);
  848.     }
  849. }
  850.  
  851. /************************************************************************/
  852. /*                                                                      */
  853. /* Convert the node text                                                */
  854. /* If Comment==TRUE, then this is really a comment in in an include     */
  855. /* file. This implies a slightly different handling.                    */
  856. /* Node is either an AutodocNodeNode or an IncludeFileNode              */
  857. /*                                                                      */
  858. /************************************************************************/
  859.  
  860. void
  861. ConvertNodeText (int Comment, void *Node)
  862.  
  863. {
  864.   enum
  865.   {
  866.     GENERIC = 0, SEE_ALSO = 1
  867.   }
  868.   Paragraph;
  869.  
  870.   Paragraph = GENERIC;
  871.   while (TRUE)
  872.     {
  873.       struct Word *Word;
  874.  
  875.       Word = ReadWord (TRUE);
  876.       if (Word->Length)
  877.     {
  878.       /* check for end of text */
  879.       if (Comment)
  880.         {
  881.           if (Word->Word[0] == '*')
  882.         {
  883.           struct Word *NextWord;
  884.  
  885.           NextWord = ReadWord (TRUE);
  886.           if (!NextWord->Newline && !NextWord->Whitespace && NextWord->Word[0] == '/')
  887.             {
  888.               WriteWord (Word);
  889.               WriteWord (NextWord);
  890.               FreeWord (Word);
  891.               FreeWord (NextWord);
  892.  
  893.               /* now, check whether the next thing is another comment. */
  894.               /* We treat this as one comment. */
  895.               Word = ReadWord (TRUE);
  896.               if (Word->Word[0] == '/')
  897.             {
  898.               NextWord = ReadWord (TRUE);
  899.               if (!NextWord->Newline && !NextWord->Whitespace && NextWord->Word[0] == '*')
  900.                 {
  901.                   WriteWord (Word);
  902.                   WriteWord (NextWord);
  903.                   FreeWord (Word);
  904.                   FreeWord (NextWord);
  905.                   continue;
  906.                 }
  907.               UnreadWord (NextWord);
  908.             }
  909.               UnreadWord (Word);
  910.               break;
  911.             }
  912.           else
  913.             {
  914.               UnreadWord (NextWord);
  915.             }
  916.         }
  917.         }
  918.       else
  919.         {
  920.           if (Word->Word[0] == '\x0c')
  921.         {
  922.           FreeWord (Word);
  923.           break;
  924.         }
  925.         }
  926.  
  927.       if (!Comment && Word->Newline && Word->Whitespace <= 4 && Node &&
  928.           strcmp(((struct AutodocNodeNode *)Node)->AutodocModuleNode->AnyNode.Name,"SAD"))
  929.         {
  930.           UnreadWord(Word);
  931.           if (IsHeadline())
  932.         {
  933.           Word=ReadWord(TRUE);
  934.           if (!strcasecmp (Word->Word, "SEE"))
  935.             {
  936.               Paragraph = SEE_ALSO;
  937.             }
  938.           else
  939.             {
  940.               Paragraph = GENERIC;
  941.             }
  942.           if (*Arguments.Version >= 39)
  943.             {
  944.               WPrintf ("@{b}");
  945.             }
  946.           do
  947.             {
  948.               WriteWord(Word);
  949.               FreeWord(Word);
  950.               Word=ReadWord(TRUE);
  951.             }
  952.           while (Word->Length && !Word->Newline);
  953.           UnreadWord(Word);
  954.           if (*Arguments.Version >= 39)
  955.             {
  956.               WPrintf ("@{ub}");
  957.             }
  958.         }
  959.           else
  960.         {
  961.           if (!AppendLine())
  962.             {
  963.               ReindentParagraph();
  964.             }
  965.         }
  966.         }
  967.       else if (!strcmp (Word->Word, "struct") ||
  968.            !strcmp (Word->Word, "union"))
  969.         {
  970.           struct Word *StructUnionTag;
  971.           struct IncludeItemNode *IncludeItemNode;
  972.  
  973.           StructUnionTag = ReadWord (FALSE);
  974.           if ((IncludeItemNode = (struct IncludeItemNode *)
  975.           SearchNode (Word->Word[0] == 'u' ? &UnionTree : &StructureTree, StructUnionTag->Word)))
  976.         {
  977.           WriteWhitespace (Word);
  978.           if (!StructUnionTag->Newline)
  979.             {
  980.               WPrintf ("@{\x22");
  981.               WriteWord (Word);
  982.             }
  983.           else
  984.             {
  985.               WriteWord (Word);
  986.               WriteWhitespace (StructUnionTag);
  987.               WPrintf ("@{\x22");
  988.             }
  989.           WriteWord (StructUnionTag);
  990.           WPrintf ("\x22 LINK \x22%s/File\x22 %lu}",
  991.             IncludeItemNode->Entries->IncludeFileNode->LinkName,
  992.                IncludeItemNode->Entries->Line);
  993.         }
  994.           else
  995.         {
  996.           WriteWord (Word);
  997.           WriteWord (StructUnionTag);
  998.         }
  999.           FreeWord (Word);
  1000.           FreeWord (StructUnionTag);
  1001.         }
  1002.  
  1003.       else if (Word->Length > 2)
  1004.         {
  1005.           if (!Word->Special && Paragraph != SEE_ALSO)
  1006.         {
  1007.           struct Word *NextWord;
  1008.  
  1009.           NextWord = ReadWord (TRUE);
  1010.           UnreadWord (NextWord);
  1011.           if (NextWord->Word[0] == '(')
  1012.             {
  1013.               if (!DoAutodoc (Word, Comment ? NULL : Node))
  1014.             {
  1015.               WriteWord (Word);
  1016.             }
  1017.               FreeWord (Word);
  1018.               continue;
  1019.             }
  1020.           if (DoHeader (Word, Comment ? Node : NULL))
  1021.             {
  1022.               FreeWord (Word);
  1023.               continue;
  1024.             }
  1025.         }
  1026.           else
  1027.         /* Word->Special == TRUE or SEE_ALSO */
  1028.         {
  1029.           if (!DoAutodoc (Word, Comment ? NULL : Node) &&
  1030.               !DoModule (Word, Comment ? NULL : Node) &&
  1031.               !DoHeader (Word, Comment ? Node : NULL))
  1032.             {
  1033.               WriteIdentifier (Word, Comment ? Node : NULL);
  1034.             }
  1035.           FreeWord (Word);
  1036.           continue;
  1037.         }
  1038.           WriteWord (Word);
  1039.           FreeWord (Word);
  1040.         }
  1041.  
  1042.       else
  1043.         {
  1044.           /* echo it normally */
  1045.           if (!DoModule (Word, Comment ? NULL : Node) &&
  1046.           !DoHeader (Word, Comment ? Node : NULL))
  1047.         {
  1048.           WriteWord (Word);
  1049.         }
  1050.           FreeWord (Word);
  1051.         }
  1052.     }
  1053.       else
  1054.     {
  1055.       /* end of file reached */
  1056.       FreeWord(Word);
  1057.       break;
  1058.     }
  1059.     }
  1060. }
  1061.  
  1062. /************************************************************************/
  1063. /*                                                                      */
  1064. /* Convert an autodoc node                                              */
  1065. /* Return FALSE for no more nodes                                       */
  1066. /*                                                                      */
  1067. /************************************************************************/
  1068.  
  1069. static int
  1070. ConvertNode (struct AutodocFileNode *AutodocFileNode)
  1071.  
  1072. {
  1073.   struct AutodocModuleNode *AutodocModuleNode;
  1074.   struct AutodocNodeNode *AutodocNodeNode;
  1075.   int Information;
  1076.   struct Word *Module;
  1077.   struct Word *Word;
  1078.   struct Word *NodeName;
  1079.  
  1080.   /* get module name ("exec.library") */
  1081.   Module = ReadWord (TRUE);
  1082.   if (!Module->Length)
  1083.     {
  1084.       FreeWord(Module);
  1085.       return FALSE;
  1086.     }
  1087.  
  1088.   Word=ReadWord (FALSE);
  1089.   if (Word->Word[0]!='/')
  1090.     {
  1091.       fprintf(stderr,"%s, line %lu: expected '/'.\n",ReadFilename,Word->Line);
  1092.       CloseAll(RETURN_ERROR);
  1093.     }
  1094.   FreeWord(Word);
  1095.  
  1096.   if (!(AutodocModuleNode = (struct AutodocModuleNode *) SearchNode (&AutodocModuleTree, Module->Word)))
  1097.     {
  1098.       fprintf (stderr, "%s, line %lu: module \x22%s\x22 not found in table of contents\n",
  1099.            ReadFilename, Module->Line, Module->Word);
  1100.       CloseAll (RETURN_ERROR);
  1101.     }
  1102.   FreeWord(Module);
  1103.  
  1104.   NodeName = ReadWord (FALSE);
  1105.   Word=ReadWord(FALSE);
  1106.   while (!Word->Newline && Word->Word[0] != '/')
  1107.     {
  1108.       FreeWord (Word);
  1109.       Word = ReadWord (FALSE);
  1110.     }
  1111.   if (Word->Newline)
  1112.     {
  1113.       UnreadWord(Word);
  1114.       Word = NodeName;
  1115.     }
  1116.   else
  1117.     {
  1118.       FreeWord (Word);
  1119.       FreeWord (NodeName);
  1120.       Word=ReadWord(FALSE);
  1121.     }
  1122.  
  1123.   Information = FALSE;
  1124.   while (Word->Word[0] == '-')
  1125.     {
  1126.       Information = TRUE;
  1127.       FreeWord (Word);
  1128.       Word = ReadWord (FALSE);
  1129.     }
  1130.  
  1131.   if (Information)
  1132.     {
  1133.       struct AutodocInfoNode *AutodocInfoNode;
  1134.  
  1135.       for (AutodocInfoNode = AutodocModuleNode->InfoNodes;
  1136.        AutodocInfoNode && strcmp (AutodocInfoNode->Name, Word->Word);
  1137.        AutodocInfoNode = AutodocInfoNode->Next)
  1138.     ;
  1139.       if (!AutodocInfoNode)
  1140.     {
  1141.       int RC;
  1142.  
  1143.       fprintf (stderr, "%s, line %lu: info-node \x22%s/%s\x22 not found in table of contents\n",
  1144.            ReadFilename, Word->Line, AutodocModuleNode->AnyNode.Name, Word->Word);
  1145.       SetRC (RETURN_WARN);
  1146.       while (Word->Length && Word->Word[0] != 0x0c)
  1147.         {
  1148.           FreeWord (Word);
  1149.           Word = ReadWord (TRUE);
  1150.         }
  1151.       RC = Word->Length;
  1152.       FreeWord (Word);
  1153.       return RC;
  1154.     }
  1155.       AutodocInfoNode->Found = TRUE;
  1156.       AutodocNodeNode = NULL;
  1157.       WPrintf ("@NODE \x22%s\x22 \x22%s/%s (information)\x22\n",
  1158.            AutodocInfoNode->Name,
  1159.            AutodocModuleNode->AnyNode.Name,
  1160.            AutodocInfoNode->Name);
  1161.     }
  1162.   else
  1163.     {
  1164.     /* !Information */
  1165.     NarratorBugFixed:
  1166.       if (!(AutodocNodeNode = (struct AutodocNodeNode *) SearchNode (&AutodocModuleNode->Nodes, Word->Word)))
  1167.     {
  1168.       int RC;
  1169.  
  1170.       /* hack: check for the famous narrator.doc bug */
  1171.       if (!strcasecmp (AutodocModuleNode->AnyNode.Name, "narrator.device") &&
  1172.           !strcmp (Word->Word, "CMD_Read"))
  1173.         {
  1174.           if (Pass2)
  1175.         {
  1176.           fprintf (stderr, "%s",
  1177.                "Hey! I just encountered the narrator.doc (CMD_Read) bug! It's still there!\n"
  1178.                "But I'm a very smart program, so of course I know how to deal with it.\n");
  1179.         }
  1180.           strcpy (Word->Word, "CMD_READ");
  1181.           goto NarratorBugFixed;
  1182.         }
  1183.       fprintf (stderr, "%s, line %lu: \x22%s/%s\x22 not found in table of contents\n",
  1184.            ReadFilename, Word->Line, AutodocModuleNode->AnyNode.Name, Word->Word);
  1185.       SetRC (RETURN_WARN);
  1186.       while (Word->Length && Word->Word[0] != 0x0c)
  1187.         {
  1188.           FreeWord (Word);
  1189.           Word = ReadWord (TRUE);
  1190.         }
  1191.       RC = Word->Length;
  1192.       FreeWord (Word);
  1193.       return RC;
  1194.     }
  1195.       AutodocNodeNode->Found = TRUE;
  1196.       WPrintf ("@NODE \x22%s%s\x22 \x22%s/%s%s\x22\n",
  1197.            AutodocNodeNode->AnyNode.Name,
  1198.            (AutodocNodeNode->AutodocNode->Function && Arguments.Parentheses) ? "()" : "",
  1199.            AutodocModuleNode->AnyNode.Name,
  1200.            AutodocNodeNode->AnyNode.Name,
  1201.            AutodocNodeNode->AutodocNode->Function ? "()" : "");
  1202.     }
  1203.  
  1204.   FreeWord (Word);
  1205.   Word = ReadWord (FALSE);
  1206.   while (!Word->Newline)
  1207.     {
  1208.       FreeWord (Word);
  1209.       Word = ReadWord (FALSE);
  1210.     }
  1211.   UnreadWord (Word);
  1212.  
  1213.   if (Pass2)
  1214.     {
  1215.       ConvertNodeText (FALSE, AutodocNodeNode);
  1216.       WPrintf ("\n\n@ENDNODE\n");
  1217.  
  1218.       return TRUE;
  1219.     }
  1220.   else
  1221.     {
  1222.       int SynopsisDone;
  1223.       int NodeCount;
  1224.       struct AVLStateInfo StateInfo;
  1225.  
  1226.       AVL_InitTraversal(&AutodocModuleNode->Nodes,&StateInfo);
  1227.       for (NodeCount=0; NodeCount<2 && AVL_InOrder(&StateInfo); NodeCount++)
  1228.     ;
  1229.  
  1230.       SynopsisDone = (NodeCount<2) || (AutodocNodeNode && !AutodocNodeNode->AutodocNode->Function);
  1231.       while (TRUE)
  1232.     {
  1233.       Word = ReadWord (TRUE);
  1234.       if (!Word->Length)
  1235.         {
  1236.           FreeWord (Word);
  1237.           return FALSE;
  1238.         }
  1239.       if (Word->Word[0] == 0x0c)
  1240.         {
  1241.           FreeWord (Word);
  1242.           return TRUE;
  1243.         }
  1244.       if (SynopsisDone)
  1245.         {
  1246.           FreeWord (Word);
  1247.           return ReadSkip () == 0x0c;
  1248.         }
  1249.       if (Word->Newline && Word->Whitespace < 5 && !strcmp ("SYNOPSIS", Word->Word))
  1250.         {
  1251.           while (TRUE)
  1252.         {
  1253.           FreeWord (Word);
  1254.           Word = ReadWord (TRUE);
  1255.           if (!Word->Length || Word->Word[0] == 0x0c)
  1256.             {
  1257.               break;
  1258.             }
  1259.           if (Word->Newline && Word->Whitespace < 5)
  1260.             {
  1261.               break;
  1262.             }
  1263.           if (Word->Length > 2)
  1264.             {
  1265.               struct Word *NextWord;
  1266.               
  1267.               NextWord = ReadWord (TRUE);
  1268.               if (NextWord->Word[0] == '(')
  1269.             {
  1270.               int NestCount;
  1271.               
  1272.               NestCount = 1;
  1273.               while (NestCount)
  1274.                 {
  1275.                   FreeWord (NextWord);
  1276.                   NextWord = ReadWord (FALSE);
  1277.                   if (NextWord->Word[0] == '(')
  1278.                 NestCount++;
  1279.                   else if (NextWord->Word[0] == ')')
  1280.                 NestCount--;
  1281.                 }
  1282.               FreeWord (NextWord);
  1283.               if (strcmp (Word->Word, AutodocNodeNode->AnyNode.Name) &&
  1284.                   !SearchNode (&AutodocModuleNode->Nodes, Word->Word))
  1285.                 {
  1286.                   struct AutodocNodeNode *VarAutodocNodeNode;
  1287.                   
  1288.                   VarAutodocNodeNode = CreateAutodocNode (Word->Word, AutodocModuleNode);
  1289.                   
  1290.                   VarAutodocNodeNode->RealNode = AutodocNodeNode;
  1291.                   VarAutodocNodeNode->Found = TRUE;
  1292.                   
  1293.                   AVL_InsertNode (&AutodocModuleNode->Nodes,
  1294.                           &VarAutodocNodeNode->AnyNode.AVLNode);
  1295.                 }
  1296.             }
  1297.               else
  1298.             {
  1299.               UnreadWord (NextWord);
  1300.             }
  1301.             }
  1302.         }
  1303.           UnreadWord (Word);
  1304.           SynopsisDone = TRUE;
  1305.         }
  1306.       else
  1307.         {
  1308.           FreeWord (Word);
  1309.         }
  1310.     }
  1311.     }
  1312.   /* not reached */
  1313. }
  1314.  
  1315. /************************************************************************/
  1316. /*                                                                      */
  1317. /* Skip the table of contents                                           */
  1318. /*                                                                      */
  1319. /************************************************************************/
  1320.  
  1321. static void
  1322. SkipTOC (void)
  1323.  
  1324. {
  1325.   struct Word *Word;
  1326.   int Done;
  1327.  
  1328.   FindTOC();
  1329.   do
  1330.     {
  1331.       Word=ReadWord(FALSE);
  1332.       Done=(Word->Word[0]==0x0c);
  1333.       FreeWord(Word);
  1334.     }
  1335.   while (!Done);
  1336. }
  1337.  
  1338. /************************************************************************/
  1339. /*                                                                      */
  1340. /* Process a single autodoc file, first pass                            */
  1341. /*                                                                      */
  1342. /************************************************************************/
  1343.  
  1344. void
  1345. ProcessAutodocFile1 (char *Filename)
  1346.  
  1347. {
  1348.   struct AutodocFileNode *AutodocFileNode;
  1349.  
  1350.   ROpen (AUTODOCDIR, Filename);
  1351.   WOpen (HYPERAUTODOCDIR, Filename);
  1352.  
  1353.   AutodocFileNode = (struct AutodocFileNode *) CreateNode (Filename, sizeof (*AutodocFileNode));
  1354.   AutodocFileNode->LinkName = xstrdup (Arguments.FullPath ? WriteFilename : Filename);
  1355.   AutodocFileNode->LinkName[strlen (AutodocFileNode->LinkName) - 4] = '\0';
  1356.   AutodocFileNode->Modules = NULL;
  1357.   AVL_InsertNode (&AutodocFileTree, &AutodocFileNode->AnyNode.AVLNode);
  1358.  
  1359.   FindTOC ();
  1360.   while (ReadTOCLine (AutodocFileNode))
  1361.     ;
  1362.  
  1363.   while (ConvertNode (AutodocFileNode))
  1364.     ;
  1365.  
  1366.   WClose ();
  1367.   RClose ();
  1368. }
  1369.  
  1370. /************************************************************************/
  1371. /*                                                                      */
  1372. /* Process a single autodoc file, second pass                           */
  1373. /*                                                                      */
  1374. /************************************************************************/
  1375.  
  1376. void
  1377. ProcessAutodocFile2 (struct AutodocFileNode *AutodocFileNode)
  1378.  
  1379. {
  1380.   printf ("Converting %s\n", AutodocFileNode->AnyNode.Name);
  1381.  
  1382.   ROpen (AUTODOCDIR, AutodocFileNode->AnyNode.Name);
  1383.   WOpen (HYPERAUTODOCDIR, AutodocFileNode->LinkName);
  1384.  
  1385.   WriteHeader (AutodocFileNode->LinkName, ReadFilename);
  1386.  
  1387.   OutputTOC (AutodocFileNode);
  1388.   SkipTOC ();
  1389.  
  1390.   while (ConvertNode (AutodocFileNode))
  1391.     ;
  1392.  
  1393.   RClose ();
  1394.   WClose ();
  1395. }
  1396.